#ifndef _MULTI_BUTTON_H_
#define _MULTI_BUTTON_H_

#include <stdint.h>
#include <string.h>

// Configuration constants - can be modified according to your needs
#define TICKS_INTERVAL       5                       // ms - timer interrupt interval
#define DEBOUNCE_TICKS       3                       // MAX 7 (0 ~ 7) - debounce filter depth
#define SHORT_TICKS          (300 / TICKS_INTERVAL)  // short press threshold
#define LONG_TICKS           (1000 / TICKS_INTERVAL) // long press threshold
#define PRESS_REPEAT_MAX_NUM 15                      // maximum repeat counter value

// Forward declaration
typedef struct _Button Button;

// Button callback function type
typedef void (*BtnCallback)(Button *btn_handle);

// Button event types
typedef enum
{
    BTN_PRESS_DOWN = 0,   // button pressed down
    BTN_PRESS_UP,         // button released
    BTN_PRESS_REPEAT,     // repeated press detected
    BTN_SINGLE_CLICK,     // single click completed
    BTN_DOUBLE_CLICK,     // double click completed
    BTN_LONG_PRESS_START, // long press started
    BTN_LONG_PRESS_HOLD,  // long press holding
    BTN_EVENT_COUNT,      // total number of events
    BTN_NONE_PRESS        // no event
} ButtonEvent;

// Button state machine states
typedef enum
{
    BTN_STATE_IDLE = 0, // idle state
    BTN_STATE_PRESS,    // pressed state
    BTN_STATE_RELEASE,  // released state waiting for timeout
    BTN_STATE_REPEAT,   // repeat press state
    BTN_STATE_LONG_HOLD // long press hold state
} ButtonState;

// Button structure
struct _Button
{
    uint16_t ticks;                                 // tick counter
    uint8_t  repeat       : 4;                      // repeat counter (0-15)
    uint8_t  event        : 4;                      // current event (0-15)
    uint8_t  state        : 3;                      // state machine state (0-7)
    uint8_t  debounce_cnt : 3;                      // debounce counter (0-7)
    uint8_t  active_level : 1;                      // active GPIO level (0 or 1)
    uint8_t  button_level : 1;                      // current button level
    uint8_t  button_id;                             // button identifier
    uint8_t (*hal_button_level)(uint8_t button_id); // HAL function to read GPIO
    BtnCallback cb[BTN_EVENT_COUNT];                // callback function array
    Button     *next;                               // next button in linked list
};

#ifdef __cplusplus
extern "C" {
#endif

// Public API functions
void button_init(Button *handle, uint8_t (*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id);
void button_attach(Button *handle, ButtonEvent event, BtnCallback cb);
void button_detach(Button *handle, ButtonEvent event);
ButtonEvent button_get_event(Button *handle);
int         button_start(Button *handle);
void        button_stop(Button *handle);
void        button_ticks(void);

// Utility functions
uint8_t button_get_repeat_count(Button *handle);
void    button_reset(Button *handle);
int     button_is_pressed(Button *handle);

#ifdef __cplusplus
}
#endif

#endif
